#include <string>
#include <vector>

using namespace std;

enum E_CELL_TYPE {e_clb,e_ioin,e_ioout};

class C_CELL {

public:
    C_CELL(const char* instname,E_CELL_TYPE type);
    C_CELL(const char* instname);
    ~C_CELL();

    void setType(E_CELL_TYPE type);
    E_CELL_TYPE getType(void);

    void setLoc(int x,int y,int z);
    void setLoc(float x,float y,float z);
    void getLoc(int& x,int& y,int& z);
    void getLoc(float& x,float& y,float& z);

    const char* getName(void);

    void setFF(bool isFF);
    bool isFF(void);

    void addFanout(unsigned int cellIdx);
    bool getFanout(vector<unsigned int>& cellIdxs);

    void addFanin(unsigned int cellIdx);
    bool getFanin(vector<unsigned int>& cellIdxs);

private:
    int _x,_y,_z;
    float _fx,_fy,_fz;
    string _name;
    bool _isFF;
    E_CELL_TYPE _type;
    vector<unsigned int> _fanout;
    vector<unsigned int> _fanin;
};

void init_3d_grid(unsigned int xdim, unsigned int ydim, unsigned int zdim);
void add_cell(const char* clbName,E_CELL_TYPE type);
C_CELL* get_cell_ptr(const char* cellName);
unsigned int get_cell_idx(const char* cellName);
bool set_cell_loc(const char* cellName,int x,int y,int z);
void place_cell_randomly(void);
void placement_statistics(float& estWL,int& interLayerWidth);
void print_network(void);
// private utilities
float _calc_SemiPerimeter(float verWght);
int _count_interlayer_bandwidth(void);
